/*
 * start.s
 *
 * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com>
 * Official site: http://xboot.org
 * Mobile phone: +86-18665388956
 * QQ: 8192542
 * 
 * Copyright(c) 2021 Cai_XL <Cai_XL@outlook.com>
 * bilibili : https://space.bilibili.com/54910927
 *
 */


#define STACK_BASE              (0x00010400)        //part of SRAM can be used as stack

#define CCU_BASE                (0x01C20000)        // CCU start address
#define CCU_PLL_STABLE_TIME     (CCU_BASE + 0x200)  
#define CCU_PLL_PERIPH_REG      (CCU_BASE + 0x28)
#define CCU_PLL_AHB_APB_REG     (CCU_BASE + 0x54)


#define GPIO_BASE               (0x01c20800)        // GPIO start address
#define GPIOE_BASE              (GPIO_BASE + 0x24 * 4)  // GPIOE start address
#define GPIOE_CFG0_REG          (GPIOE_BASE + 0x00)
#define GPIOE_DATA_REG          (GPIOE_BASE + 0x10)
#define GPIOE_DRV0_REG          (GPIOE_BASE + 0x14)
#define GPIOE_PUL0_REG          (GPIOE_BASE + 0x1c)

	.arm
	.global	_start
    .section .boothead,"a",%progbits
	.type	_start, %object
	.size	_start, .-_start
_start:
	/* Boot head information for BROM */
	.long 0xea000016        // 0x00-0x03 -> b 0x60   
	.byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0'	// 0x04-0x0b -> "eCON.BT0"
	.long 0                 // 0x0c-0x0f -> CheckSum
    .long 0x8000			// 0x10-0x13 -> Size(32KiB in default)
	.byte 'S', 'P', 'L'     // 0x14-0x16 -> "sunxi" marker
    .byte 2					// 0x17-0x17 -> Version=2
	.long 0                 // 0x18-0x1b -> fel_script_address
    .long 0	                // 0x1c-0x1f -> fel_uEnv_length								
	.long 0                 // 0x20-0x23 -> dt_name_offset
    .long 0                 // 0x24-0x27 -> reserved1
    .long 0                 // 0x28-0x2b -> boot_media
    // uint32_t str_pool[13]; (not used by onchip loader)
    .long 0                 // 0x2c-0x2f
    .long 0                 // 0x30-0x33
    .long 0                 // 0x34-0x37
    .long 0                 // 0x38-0x3b
    .long 0					// 0x3c-0x3f
    // isr_table and isr entries use 0x00-0x3f (15*uint32_t)
	.long 0					// 0x40-0x43 -> sp
	.long 0					// 0x44-0x47 -> lr
	.long 0					// 0x48-0x4b -> cpsr
	.long 0					// 0x4c-0x4f -> cp15.c1
	.long 0					// 0x50-0x53 -> cp15.c1	
	.long 0					// 0x54-0x57 -> BOOT_DEVICE
	.long 0					// 0x58-0x5b 
	.long 0					// 0x5c-0x5f 	
isr_table:	
    b	reset
	ldr	pc, _undefined_instruction
	ldr	pc, _software_interrupt
	ldr	pc, _prefetch_abort
	ldr	pc, _data_abort
	ldr	pc, _not_used
	ldr	pc, _irq
	ldr	pc, _fiq
_undefined_instruction:
    .word infinite_loop
_software_interrupt:
    .word infinite_loop
_prefetch_abort:
    .word infinite_loop
_data_abort:
    .word infinite_loop
_not_used:
    .word infinite_loop
_irq:
    .word infinite_loop
_fiq:
    .word infinite_loop
infinite_loop:
	b infinite_loop  // isr is invalid for spl

    .align 4
    .type	reset, %function
reset:  // 复位响应入口
    mrs r0, cpsr
	bic r0, r0, #0x1f
	orr r0, r0, #0xd3
	msr cpsr, r0

    ldr sp,=__estack // set stack

    // CCU init
    ldr r0,= CCU_PLL_STABLE_TIME
    ldr r1,= 0x01ff
    str r1,[r0]

    ldr r0,= CCU_PLL_PERIPH_REG
    ldr r1,= 0x80041800
    str r1,[r0]

    ldr r0,= CCU_PLL_AHB_APB_REG
    ldr r1,= 0x00003180
    str r1,[r0]


    bl delay

    // GPIO init
    ldr r0,= GPIOE_CFG0_REG
    ldr r1,= 0x1111 // all output
    str r1,[r0]

    ldr r0,= GPIOE_DRV0_REG
    ldr r1,= 0xff // all drive level 3
    str r1,[r0]

    ldr r0,= GPIOE_PUL0_REG
    ldr r1,= 0x55 // all pull-up
    str r1,[r0]

    ldr r0,= GPIOE_DATA_REG
    mov r1,#0x0f
    str r1,[r0]
    
loop:
    ldr r0,= GPIOE_DATA_REG
    mov r1,#0x0f
    str r1,[r0]
    bl delay


    ldr r0,= GPIOE_DATA_REG
    mov r1,#0x00
    str r1,[r0]
    bl delay

    b loop


    .align 4
    .type	delay, %function
delay:
    ldr r2,=200000
delay_loop:
    cmp r2,#0
    moveq pc,lr
    sub r2, r2, #1
    b delay_loop